package spring.data.jpa.config;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.data.jpa.repository.support.SimpleGenericJpaRepository;
import org.springframework.data.repository.config.NamedQueriesBeanDefinitionBuilder;
import org.springframework.data.repository.config.RepositoryConfiguration;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;

import spring.data.jpa.repository.CommonJpaRepository;

public class SimpleRepositoryBeanDefinitionBuilder {

    public BeanDefinitionBuilder build(RepositoryConfiguration<?> configuration,
            RepositoryConfigurationExtension extension) {

        BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(configuration
                .getRepositoryFactoryBeanClassName());

        builder.getRawBeanDefinition().setSource(configuration.getSource());
        builder.addPropertyValue("lazyInit", configuration.isLazyInit());
        builder.setLazyInit(configuration.isLazyInit());

        configuration.getRepositoryBaseClassName()//
                .ifPresent(it -> builder.addPropertyValue("repositoryBaseClass", it));

        NamedQueriesBeanDefinitionBuilder definitionBuilder = new NamedQueriesBeanDefinitionBuilder(
                extension.getDefaultNamedQueryLocation());
        configuration.getNamedQueriesLocation().ifPresent(definitionBuilder::setLocations);

        builder.addPropertyValue("namedQueries", definitionBuilder.build(configuration.getSource()));

        // ///
        String domainClassName = configuration.getRepositoryInterface();
        Class<?> domainClass;
        try {
            domainClass = Class.forName(domainClassName);
        } catch (ClassNotFoundException e) {
            throw new BeanCreationException("Domain class not found.", e);
        }
        builder.addPropertyValue("domainClass", domainClass);
        builder.addPropertyValue("repositoryInterface", CommonJpaRepository.class);
        builder.addPropertyValue("repositoryClass", SimpleGenericJpaRepository.class);
        builder.addConstructorArgValue(CommonJpaRepository.class);
        builder.addConstructorArgValue(domainClass);
        return builder;
    }
}
